#include "main.h"

// 全局共享变量
char myIP[16] = {0}; //自身ip

int main(void)
{
    pthread_t wait_respond, msg_pro;
    msg_manage_init(); //消息队列服务初始化
    init_friends_link();
    pthread_create(&wait_respond, NULL,
                   &wait_for_otherClient_to_respond, NULL); //创建监听服务线程
    pthread_create(&msg_pro, NULL, &msg_processing, NULL);  //创建解析服务线程

    service_init(); //开启上线服务

    // 发送后等待接收响应报文
    printf("Searching for friends ");
    fflush(stdout);
    for (int i = 0; i < 5; i++)
    {
        printf(".");
        fflush(stdout);
        sleep(1);
    }
    printf("\n");
    printf("Searching for friends done.\n");

    // TODO 选择操作
    int select_mode;
    while (1)
    {
        select_mode = print_ui(); //打印操作UI
        printf("ret = %d\n", select_mode);
        switch (select_mode)
        {
        case MODE_BROWSE_F_LIST:
            Refresh_friends_list(); //刷新
            friends_print();        //打印
            break;
        case MODE_CHAT:
            chat();
            break;
        case MODE_GROUP:
            // 群聊
            break;
        case MODE_SEND_FILE:
            // 发送文件
            break;
        case MODE_OFFLINE:
            offline(); //下线后推出程序
            break;
        default:
            break;
        }
    }

    return 0;
}

void service_init()
{
    // 获取自己的IP，通信时把自己的IP端口信息带上
    //get_myIP(myIP);

    //发送广播包，向所有客户端收到之后马上返回
    // 封装数据包
    data_packet *send_d_p = malloc(sizeof(data_packet));
    if (send_d_p == NULL)
    {
        perror("malloc");
        return;
    }

    bzero(send_d_p, sizeof(send_d_p)); //清零

    send_d_p->ip = inet_addr(DEST_IP);   //ip
    send_d_p->port = htons(DEST_PORT);   //port
    send_d_p->connect_type = 1;          //UDP连接
    send_d_p->packet_type = PACK_ONLINE; //上线报文格式
    send_d_p->length = 0;                //数据长度为0

    send_data(send_d_p, NULL);
}

/**
 * @brief Get the local ip object
 * 
 * @param ip 要存放ip地址字符串的首地址
 * @param len 要存放的长度
 * @return int 成功返回0，失败返回负值
 */
/*
int get_local_ip(char *ip, int len)
{
    if ((ip == NULL) || (len < 16))
    {
        printf("####L(%d) fail....\n", __LINE__);
        return -1;
    }
    memset(ip, 0x0, len); //清空
    int sock_get_ip;

    struct sockaddr_in *sin;
    struct ifreq ifr_ip;

    if ((sock_get_ip = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        printf("####L(%d) socket create fail...get_local_ip!\n", __LINE__);
        return -1;
    }

    memset(&ifr_ip, 0, sizeof(ifr_ip));
    //获取网口的IP
    strncpy(ifr_ip.ifr_name, "ens33", sizeof(ifr_ip.ifr_name) - 1);

    if (ioctl(sock_get_ip, SIOCGIFADDR, &ifr_ip) < 0)
    {
        printf("####L(%d) fail......\n", __LINE__);
        close(sock_get_ip);
        return -1;
    }
    sin = (struct sockaddr_in *)&ifr_ip.ifr_addr;
    strcpy(ip, inet_ntoa(sin->sin_addr));

    printf("####L(%d) local ip:%s \n", __LINE__, ip);
    close(sock_get_ip);

    return 0;
}*/
// ————————————————
// 版权声明：本文为CSDN博主「清荣茂多趣味」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
// 原文链接：https://blog.csdn.net/journey0804/article/details/69397669

/**
 * @brief 刷新好友列表
 * 
 */
void Refresh_friends_list(void)
{
    // 清空当前列表信息
    uninit_friends_link();
    init_friends_link();
    service_init();

    // 发送后等待接收响应报文
    printf("Searching for friends ");
    fflush(stdout);
    for (int i = 0; i < 5; i++)
    {
        printf(".");
        fflush(stdout);
        sleep(1);
    }
    printf("\n");
    printf("Searching for friends done.\n");
}

/**
 * @brief 打印操作ui，并返回操作的对象
 * 
 * @return int 详情参见函数
 */
int print_ui(void)
{
    int input_mode;
    printf("=================================================\n");
    printf("\t\t飞秋(低仿)\t\t\n");
    printf("1.查看在线好友\n");
    printf("2.新建对话\n");
    printf("3.创建群聊对象\n");
    printf("4.发送文件\n");
    printf("5.下线\n");
    printf("=================================================\n");
    printf("请选择：");
    // printf("here is a test.\n");
    scanf("%d", &input_mode);
    getchar(); //吸收换行符
    // printf("input_mode=%d\n", input_mode);
    switch (input_mode)
    {
    case MODE_BROWSE_F_LIST:
    case MODE_CHAT:
    case MODE_GROUP:
    case MODE_SEND_FILE:
    case MODE_OFFLINE:
        return input_mode;
        break;
    default:
        printf("input error, please try again.\n");
        return print_ui(); // 错误的话递归调用
        break;
    }
}

/**
 * @brief 下线，下线后退出程序
 * 
 */
void offline(void)
{
    // 封装数据包
    data_packet *send_d_p = malloc(sizeof(data_packet));
    bzero(send_d_p, sizeof(send_d_p));    //清零
    send_d_p->ip = inet_addr(DEST_IP);    //ip
    send_d_p->port = htons(DEST_PORT);    //port
    send_d_p->connect_type = 1;           //UDP连接
    send_d_p->packet_type = PACK_OFFLINE; //下线报文格式
    send_d_p->length = 0;                 //数据长度为0

    // 发送后关闭
    send_data(send_d_p, "");
    printf("exit......\n");
    exit(0);
}

void chat(void)
{
    int input_len;
    char ip_str[16] = {0};
    char *input_buf = malloc(REC_MAX);
    data_packet *d_p = malloc(sizeof(data_packet));

    printf("请输入好友的IP(回车结束输入)：");
    scanf("%[^\n]", ip_str);
    getchar(); //吸收换行符

    bzero(input_buf, sizeof(input_buf));
    printf("请输入要发送的消息(回车结束输入)：\n");
    scanf("%[^\n]", input_buf);
    getchar(); //吸收换行符
    input_len = strlen(input_buf);

    //发送
    bzero(d_p, sizeof(d_p));
    d_p->ip = inet_addr(ip_str);
    d_p->port = htons(DEST_PORT);
    d_p->length = input_len;
    d_p->packet_type = PACK_MSG; //消息报文
    send_data(d_p, input_buf);
    printf("发送成功。%s\n", input_buf);
}
